/*Package fastrand
 *@Author liming.dirac 2022/9/2 17:13:51
 *@Description:
 */
package fastrand

// U32 返回 32 位无符号伪随机数
var U32 = runtimeFastRandU32

// U64 返回 64 位无符号伪随机数
var U64 = runtimeFastRandU64

// I31 返回 32 位有符号非负伪随机数
func I31() int32 {
	return int32(U32()) & (1<<31 - 1) // 只取低31位
}

// I63 返回 64 位有符号非负伪随机数
func I63() int64 {
	return int64(U64() & (1<<64 - 1)) // 只取低63位
}

// Int 返回有符号非负伪随机数
func Int() int {
	return int(I63())
}

// U32n 返回 [0,n) 的 32 位无符号伪随机数
func U32n(n uint32) uint32 {
	return uint32(uint64(U32()) * uint64(n) >> 32)
}

// U64n 返回 [0,n) 的 64 位无符号伪随机数
func U64n(n uint64) uint64 {
	return U64() % n
}

// I31n 返回 [0,n) 的有符号非负伪随机数
func I31n(n int32) int32 {
	if n < 0 {
		panic("argument for I31n must be non-negative")
	}
	return int32(I64n(int64(n)))
}

func I64n(n int64) int64 {
	if n < 0 {
		panic("argument for I64n must be non-negative")
	}
	if n&(n-1) == 0 { // n 为 2 的倍数，使用 n-1 的掩码即可
		return I63() & (n - 1)
	}
	max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) // int63 内 n 的倍数的最大值
	v := I63()
	for v > max { // 只有 v <= max，模余 n 的分布才是均匀的
		v = I63()
	}
	return v % n
}
